package com.zoe.onelink.auth.component;

import cn.hutool.http.HttpStatus;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zoe.onelink.common.entity.ResultVO;
import com.zoe.onelink.common.enumeration.ExceptionCodeEnum;
import com.zoe.onelink.common.enumeration.UpmsExceptionCodeEnum;
import com.zoe.onelink.core.util.LocaleResolverUtil;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * <p>标题: </p>
 * <p>描述: 客户端异常处理 1. 可以根据 AuthenticationException 不同细化异常处理</p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-02-24 15:16
 */
@Slf4j
@RequiredArgsConstructor
public class ResourceAuthExceptionEntryPoint implements AuthenticationEntryPoint {

    private final ObjectMapper objectMapper;

    @Override
    @SneakyThrows
    public void commence(
            HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
        ResultVO result = new ResultVO<>();
        result.setCode(ExceptionCodeEnum.BIZ_ERROR.getCode());
        if (authException != null) {
            result.setError(authException.getMessage());
        }

        // 针对令牌过期返回特殊的状态码
        if (authException instanceof InsufficientAuthenticationException) {
            String message = null;
            try{
                message = LocaleResolverUtil.getMessage(UpmsExceptionCodeEnum.UPMS_AUTH_TOKEN_INVALID, null);
            } catch (Exception e){
                message = "登录状态失效或已过期";
            }
            result.setCode(UpmsExceptionCodeEnum.UPMS_AUTH_TOKEN_INVALID.getCode());
            result.setMessage(message);
        }

        PrintWriter printWriter = response.getWriter();
        printWriter.append(objectMapper.writeValueAsString(result));
    }
}
